﻿using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Casamiel.API.Application;
using Casamiel.API.Application.Commands;
using Casamiel.API.Application.Models;
using Casamiel.API.Application.Models.V2;
using Casamiel.API.Application.Services;
using Casamiel.API.Infrastructure;
using Casamiel.API.Infrastructure.Filters;
using Casamiel.API.Infrastructure.Middlewares;
using Casamiel.API.Infrastructure.Wxpay;
using Casamiel.Application;
using Casamiel.Application.Commands;
using Casamiel.Common;
using Casamiel.Common.Extensions;
using Casamiel.Domain;
using Casamiel.Domain.Entity;
using Casamiel.Domain.Request;
using Casamiel.Domain.Response;
using Casamiel.Domain.Response.IC;
using Enyim.Caching;
using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NLog;

namespace Casamiel.API.Controllers.V2
{
    /// <summary>
    /// 
    /// </summary>
    [Produces("application/json")]
    [ApiVersion("2.0")]
    [Route("api/v{api-version:apiVersion}/WxApp")]
    [Authorize]
    [ApiController]
    [EnableCors("any")]
    public class WxAppController : BaseController
    {
        private readonly IWxService _wxService;
        private readonly IMemberService _memberService;
        private readonly IMobileCheckCode _mobileCheckCode;
        //private readonly IUserLogService _userLog;
        private readonly NLog.ILogger logger = NLog.LogManager.GetLogger("WxAppService");
        private readonly IIcApiService _iicApiService;
        private readonly ICacheService _cacheService;
        private readonly IMemberCardService _memberCard;
        private readonly IPaymentService _paymentService;
        private readonly CasamielSettings _settings;
        private readonly IHttpClientFactory _clientFactory;
        private readonly ITokenProvider _tokenProvider;
        private readonly IMediator _mediator;
        private readonly IMemcachedClient _memcachedClient;
        private readonly string MemcachedPre;


        /// <summary>
        /// 
        /// </summary>
        /// <param name="wxLogin"></param>
        /// <param name="memberService"></param>
        /// <param name="mobileCheckCode"></param>
         /// <param name="cacheService"></param>
        /// <param name="iicApiService"></param>
        /// <param name="memberCard"></param>
        /// <param name="payment"></param>
        /// <param name="casamielSettings"></param>
        /// <param name="httpClient"></param>
        /// <param name="tokenProvider"></param>
        /// <param name="mediator"></param>
        /// <param name="memcachedClient"></param>
        public WxAppController(IWxService wxLogin, IMemberService memberService, IMobileCheckCode mobileCheckCode,
             ICacheService cacheService, IIcApiService iicApiService,
            IMemberCardService memberCard, IPaymentService payment,
            IOptionsSnapshot<CasamielSettings> casamielSettings, IHttpClientFactory httpClient, ITokenProvider tokenProvider,
                                IMediator mediator, IMemcachedClient memcachedClient)
        {
            if (casamielSettings == null) {
                throw new ArgumentNullException(nameof(casamielSettings));
            }
            _wxService = wxLogin;
            _memberService = memberService;
            _mobileCheckCode = mobileCheckCode;
             _cacheService = cacheService;
            _iicApiService = iicApiService;
            _memberCard = memberCard;
            _paymentService = payment;
            _settings = casamielSettings.Value;
            _clientFactory = httpClient;
            _tokenProvider = tokenProvider;
            _mediator = mediator;
            _memcachedClient = memcachedClient;
            MemcachedPre = casamielSettings.Value.MemcachedPre;
        }
        /// <summary>
        /// 获取优惠卷
        /// </summary>
        /// <returns>The coupon.</returns>
        /// <param name="req">Req.</param>
        /// <param name="token">Token.</param>
        [HttpPost]
        [Route("[action]")]
        [TypeFilterAttribute(typeof(CheckTokenAttribute))]
        public async Task<ActionResult<BaseResult<string>>> GetCoupon([FromBody] GetCouponReq req, [FromHeader(Name = "u-token")] string token)
        {
            if (req == null) {
                throw new ArgumentNullException(nameof(req));
            }
            logger.Trace($"GetCoupon:{JsonConvert.SerializeObject(req)}");

            var mobile = MemberHelper.GetMobile(token);
            var command = new CreateMemberCouponCommand(req.ActivityId, mobile);
            return await _mediator.Send(command).ConfigureAwait(false);
        }


        /// <summary>
        /// 会员申请会员卡
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("[action]")]
        [TypeFilterAttribute(typeof(CheckTokenAttribute))]
        public async Task<BaseResult<MemberIcselfregistResponse>> MemberIcselfregist([FromHeader(Name = "u-token")] string token)
        {
            var mobile = MemberHelper.GetMobile(token);
            var command = new MemberIcselfregistCommand(mobile, $"{LoginInfo.Item3}099".ToInt32(0)) { RequestUrl = Request.GetShortUri(), UserIP = Request.GetUserIp() };
            var result = await _mediator.Send(command).ConfigureAwait(false);
            var res = new MemberIcselfregistResponse {
                 IsNewShop=0
            };
            if (result.code == 0) {
                var cardentity = await _memberCard.GetBindCardAsync<ICasaMielSession>(mobile).ConfigureAwait(false);
                if (cardentity != null) {
                    res.Cardno = cardentity.CardNO;
                    var updatecommand = new UpdateWxExtensionCommand(mobile, cardentity.CardNO);
                    var s= await _mediator.Send(updatecommand).ConfigureAwait(false);
                    if (s) {
                        res.IsNewShop = 1;
                    }
                }
            }
            return new BaseResult<MemberIcselfregistResponse>(res, result.code, result.msg);
        }


         /// <summary>
        /// 会员绑卡
        /// </summary>
        /// <param name="command"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("[action]")]
        [TypeFilterAttribute(typeof(CheckTokenAttribute))]
        public async Task<BaseResult<MemberBindCardResponse>> MemberBindCard([FromBody] BindMemberCardCommand command, [FromHeader(Name = "u-token")]  string token)
        {
            if (command == null) {
                throw new ArgumentNullException(nameof(command));
            }

            var mobile = MemberHelper.GetMobile(token);
            //if (mobile != command.Mobile)
            //{
            //    return new Zmodel { code = -17, msg = "手机号不符" };
            //}

            var res = new MemberBindCardResponse {
                Cardno = command.Cardno,
                IsNewShop = 0
            };
            command.Mobile = mobile;
            command.UserIP = Request.GetUserIp();
            command.RequestUrl = Request.GetShortUri();
            command.Source = 11;
            var result = await _mediator.Send(command).ConfigureAwait(false);
            if (result.code == 0) {
                var rnt = JsonConvert.DeserializeObject<JObject>(result.content);

                res.largessmoney = rnt["largessmoney"].ToDecimal(0);
                res.cardtypename = rnt["cardtypename"].ToString();
                res.description= rnt["description"].ToString();
                var cardentity = await _memberCard.GetBindCardAsync<ICasaMielSession>(mobile).ConfigureAwait(false);
                if (cardentity != null) {
                    var updatecommand = new UpdateWxExtensionCommand(mobile, cardentity.CardNO);
                    var s=  await _mediator.Send(updatecommand).ConfigureAwait(false);
                    if (s) {
                        res.IsNewShop = 1;
                    }
                }
            }
            return new BaseResult<MemberBindCardResponse>(res, result.code, result.msg);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("[action]")]
        [TypeFilterAttribute(typeof(CheckTokenAttribute))]
        public async Task<BaseResult<string>> Createwxaqrcode([FromBody] CreatewxaqrcodeRequest request) 
        {
            var appId = "wx3961257c61049cb4";//csasa商城

            var _cacheKey = MemcachedPre + Constant.MINIAPPPTOKEN + appId;
            var entity = await _memcachedClient.GetValueAsync<string>(_cacheKey).ConfigureAwait(false);
            var _client = _clientFactory.CreateClient("weixin");
            if (string.IsNullOrEmpty(entity)) {

                var list = await _wxService.GetMiniAppSettingsList<ICasaMielSession>().ConfigureAwait(false);

                var w = list.FirstOrDefault(c => c.Sort == 0);
                string url = "cgi-bin/token?"; //grant_type=client_credential&appid=APPID&secret=APPSECRET";//https://api.weixin.qq.com/
                string param = string.Format(System.Globalization.CultureInfo.CurrentCulture, "appid={0}&secret={1}&grant_type={2}", w.AppId, w.Secret, "client_credential");
               

                string result = "";
                using (var requestMessage = new HttpRequestMessage(HttpMethod.Get, url + param)) {
                    using (var response = await _client.SendAsync(requestMessage).ConfigureAwait(false)) {
                        if (response.IsSuccessStatusCode) {

                            result = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
                        } else {
                            throw new HttpRequestException();
                        }
                    }
                }

                var wxopenInfo = JsonConvert.DeserializeObject<dynamic>(result);
                entity = wxopenInfo.access_token;

                // long expires_in = wxopenInfo.expires_in;
                await _memcachedClient.AddAsync(_cacheKey, entity, 7000).ConfigureAwait(false);
            }
            
            string content="";
           // string path = $"{AppContext.BaseDirectory}//logs//casashop//{shopid}.png";
            //var client = _clientFactory.CreateClient("");
            using (var requestMessage = new HttpRequestMessage(HttpMethod.Post, $"wxa/getwxacodeunlimit?access_token={entity}")) {
                var data = new { scene=request.Scene, width=request.Width };
                requestMessage.Content = new StringContent(JsonConvert.SerializeObject(data), System.Text.Encoding.UTF8, "application/json");
                using (var response = await _client.SendAsync(requestMessage).ConfigureAwait(false)) {

                    if (response.IsSuccessStatusCode) {
                        if (response.Content.Headers.ContentType.MediaType == "image/jpeg") {

                            //content = Convert.ToBase64String(await response.Content.ReadAsByteArrayAsync().ConfigureAwait(false));
                            using (var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false)) {
                                byte[] bytes = new byte[stream.Length];
                                stream.Read(bytes, 0, bytes.Length);
                                // 设置当前流的位置为流的开始
                                stream.Seek(0, SeekOrigin.Begin);
                                // await System.IO.File.WriteAllBytesAsync(path, bytes).ConfigureAwait(false);
                                content = Convert.ToBase64String(bytes);


                            }
                        } else {
                            var result1 = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
                            return new BaseResult<string>("", 999, result1);
                        }

                    }
                }
            }
            return new BaseResult<string>(content, 0, "");
        }
        /// <summary>
        /// 检查是否领券
        /// </summary>
        /// <returns>The coupon.</returns>
        /// <param name="req">Req.</param>
        /// <param name="token">Token.</param>
        [HttpPost]
        [Route("[action]")]
        [TypeFilterAttribute(typeof(CheckTokenAttribute))]
        public async Task<ActionResult<BaseResult<bool>>> CheckCoupon([FromBody] GetCouponReq req, [FromHeader(Name = "u-token")] string token)
        {
            if (req == null) {
                throw new ArgumentNullException(nameof(req));
            }
            logger.Trace($"CheckCoupon:{JsonConvert.SerializeObject(req)}");

            var mobile = MemberHelper.GetMobile(token);
            var command = new CheckMemberCouponCommand(req.ActivityId, mobile);
            return await _mediator.Send(command).ConfigureAwait(false);
        }

        /// <summary>
        /// Saves the form identifier.
        /// </summary>
        /// <returns>The form identifier.</returns>
        /// <param name="req">Req.</param>
        [HttpPost]
        [Route("[action]")]
        public  IActionResult SaveFormId([FromBody] WxSaveFormIdReq req)
        {
            if (req == null) {
                throw new ArgumentNullException(nameof(req));
            }
            //var command = new SaveWxFormIdCommand(req.Id, req.FormId);
            //await _mediator.Send(command).ConfigureAwait(false);
            //logger.Trace($"{ JsonConvert.SerializeObject(req)}");
            return Ok(new { code = 0, msg = "" });
        }

        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("[action]")]
        public async Task<IActionResult> Login([FromBody] Casamiel.API.Application.Models.V2.WechatLogin data)
        {
            if (data == null) {
                throw new ArgumentNullException(nameof(data));
            }
            logger.Trace($"wechatlogin:{JsonConvert.SerializeObject(data)}");
            var openid = "";
            string appid = data.Appid;
            var miniappentity = await _wxService.FindAsync<ICasaMielSession>(appid).ConfigureAwait(false);
            if (miniappentity == null) {
                return new JsonResult(new { code = 999, msg = "小程序未配置" });
            }
            WxPayData wdata = new WxPayData();
            wdata.SetValue("appid", appid);
            wdata.SetValue("secret", miniappentity.Secret);
            wdata.SetValue("js_code", data.Code);
            wdata.SetValue("grant_type", "authorization_code");
            //string url = "https://api.weixin.qq.com/sns/jscode2session?" + wdata.ToUrl();
            string url = "sns/jscode2session?" + wdata.ToUrl();
            var client = _clientFactory.CreateClient("weixin");
            string result = "";
            using (var request = new HttpRequestMessage(HttpMethod.Get, url)) {
                using (var response = await client.SendAsync(request).ConfigureAwait(false)) {
                    if (response.IsSuccessStatusCode) {
                        result = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
                    }
                }
            }

            try {
                var wxopenInfo = JsonConvert.DeserializeObject<dynamic>(result);
                logger.Info($"miniapplogin:{JsonConvert.SerializeObject(wxopenInfo)}");
                //获取用户openid
                openid = wxopenInfo.openid;
                if (openid == null) {
                    return new JsonResult(new { code = 400, data = wxopenInfo });
                }
                var unionId = wxopenInfo.unionId;
                if (string.IsNullOrEmpty(unionId)) {
                    unionId = "";

                }
                WxOpenId userinfo = await _wxService.GetAsync<ICasaMielSession>(openid, appid).ConfigureAwait(false);
                if (userinfo == null) {
                    if (string.IsNullOrEmpty(unionId)) {
                        unionId = "";
                    }
                    userinfo = new WxOpenId { AppId = appid, OpenId = openid, UnionId = unionId, Session_key = wxopenInfo.session_key, Create_time = DateTime.Now };
                    //await  wxService.AddAsync<ICasaMielSession>(userinfo);
                    try {
                        await _wxService.AddAsync<ICasaMielSession>(userinfo).ConfigureAwait(false);
                    } catch (SqlException ex) {
                        if (ex.Number == 2627 || ex.Number != 2601) {
                            userinfo = await _wxService.GetAsync<ICasaMielSession>(openid, appid).ConfigureAwait(false);
                        } else {
                            throw;
                        }
                    }
                } else {
                    userinfo.Session_key = wxopenInfo.session_key;
                    //userinfo.Update_time = DateTime.Now;
                    if (!string.IsNullOrEmpty(unionId)) {
                        userinfo.UnionId = unionId;
                    }
                    await _wxService.UpdateAsync<ICasaMielSession>(userinfo).ConfigureAwait(false);
                }

                if (!string.IsNullOrEmpty(unionId)) {
                    var userentity = await _wxService.GetByUnionIdAsync<ICasaMielSession>(unionId).ConfigureAwait(false);
                    if (userentity != null) {
                        return new JsonResult(new { code = 0, id = userinfo.Id, isBind = false });
                    }
                }
                if (string.IsNullOrEmpty(userinfo.Mobile)) {
                    return new JsonResult(new { code = 0, id = userinfo.Id, isBind = false });
                }
                return new JsonResult(new { code = 0, id = userinfo.Id, isBind = true });
            } catch (Exception) {
                throw;
            }
        }
        /// <summary>
        /// 绑定手机号
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("[action]")]
        public async Task<IActionResult> BindMobile([FromBody]Application.Models.WxAppBindMobileReq data)
        {
            if (data == null) {
                throw new ArgumentNullException(nameof(data));
            }
            logger.Trace($"BindMobile:{JsonConvert.SerializeObject(data)}");
            ConsoleHelper.DoLog(data, Request);
            if (data.id == 0) {
                logger.Error($"BindMobile-----ip:{Request.GetUserIp()}id不存在");

                var json = new JsonErrorResponse {
                    code = 999,
                    msg = "id不存在"
                };
                return new JsonResult(json);
            }
            var sucess = _mobileCheckCode.CheckCode(data.mobile, data.yzm, false);

            if (sucess["Success"].ToString().ToLower(CultureInfo.CurrentCulture) == "false") {
                return new JsonResult(new { code = "-2", msg = sucess["msg"].ToString() });
            }
            var member = await _memberService.FindAsync<ICasaMielSession>(data.mobile).ConfigureAwait(false);
            if (member == null) {
                member = new Member { Mobile = data.mobile, CreateDate = DateTime.Now, LastLoginDate = DateTime.Now, Source = 2 };
                try {
                    await _memberService.AddAsync<ICasaMielSession>(member).ConfigureAwait(false);
                } catch (SqlException ex) {
                    if (ex.Number == 2627) {
                        member = await _memberService.FindAsync<ICasaMielSession>(data.mobile).ConfigureAwait(false);
                        member.LastLoginDate = DateTime.Now;
                        await _memberService.UpdateLastLoginDateAsync<ICasaMielSession>(member.ID, DateTime.Now).ConfigureAwait(false);
                        //await _memberService.UpdateAsync<ICasaMielSession>(member).ConfigureAwait(false);
                    }
                }
            } else {
                member.LastLoginDate = DateTime.Now;
                await _memberService.UpdateLastLoginDateAsync<ICasaMielSession>(member.ID, DateTime.Now).ConfigureAwait(false);
                //await _memberService.UpdateAsync<ICasaMielSession>(member).ConfigureAwait(false);
            }
            var userinfo = await _wxService.GetByIdAsync<ICasaMielSession>(data.id).ConfigureAwait(false);
            if (userinfo == null) {
                var json = new JsonErrorResponse {
                    code = 999,
                    msg = "很抱歉，出错了"
                };
                return new JsonResult(json);
            }

            userinfo.Mobile = data.mobile;
            userinfo.Update_time = DateTime.Now;
            // Console.WriteLine($"updatewxopeid:{JsonConvert.SerializeObject(userinfo)}");
            await _wxService.UpdateAsync<ICasaMielSession>(userinfo).ConfigureAwait(false);
            if (!string.IsNullOrEmpty(data.Scene)) {
                Regex reg = new Regex(@"shopid=(\d*)");
                Match match = reg.Match(data.Scene);
                string value = match.Groups[1].Value;
                if (!string.IsNullOrEmpty(value)) {
                    var command = new CreateWxExtensionCommand(userinfo, value.ToInt32(0));
                    await _mediator.Send(command).ConfigureAwait(false);
                }

            } else {
                var command = new CreateWxExtensionCommand(userinfo, 0);
                await _mediator.Send(command).ConfigureAwait(false);
            }

            var tokens = _tokenProvider.GenerateToken(data.mobile);
            var userAgent = string.IsNullOrEmpty(Request.Headers["User-Agent"].ToString()) ? Request.Headers["UserAgent"].ToString() : Request.Headers["User-Agent"].ToString();
            int loginType = userAgent.Contains("CASAMIEL", StringComparison.CurrentCulture) ? 1 : 2;
            if (userAgent.Contains("MicroMessenger", StringComparison.CurrentCulture)) {
                loginType = 3;
            }

            var m = await _memberService.FindAsync<ICasaMielSession>(data.mobile, loginType).ConfigureAwait(false);
            if (m != null) {
                logger.Trace($"mobile:{m.Mobile},{m.UpdateTime.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.CurrentCulture)},totaldays{DateTime.Now.Subtract(m.UpdateTime).TotalDays}");

                if (DateTime.Now.Subtract(m.UpdateTime).TotalDays > 8 || string.IsNullOrEmpty(m.Access_Token)) {
                    m.Access_Token = tokens.access_token;
                    m.UpdateTime = DateTime.Now;
                } else {
                    tokens.access_token = m.Access_Token;
                    tokens.expires_in = m.Expires_In;
                }
                m.Login_Count++;
                m.Expires_In = tokens.expires_in;
                m.Resgistration_Id = "";
                await _memberService.UpdateAsync<ICasaMielSession>(m).ConfigureAwait(false);
                //m.Access_Token = tokens.access_token;
                //m.UpdateTime = DateTime.Now;
                //m.Login_Count++;
                //m.Expires_In = tokens.expires_in;
                //m.Resgistration_Id = data.registration_Id;
                //await _memberService.UpdateAsync<ICasaMielSession>(m).ConfigureAwait(false);
            } else {
                m = new MemberAccessToken {
                    Access_Token = tokens.access_token,
                    CreateTime = DateTime.Now,
                    UpdateTime = DateTime.Now,
                    Login_Count = 1,
                    Login_Type = loginType,
                    Mobile = data.mobile,
                    Expires_In = tokens.expires_in,
                    Resgistration_Id = data.registration_Id
                };
                await _memberService.AddAsync<ICasaMielSession>(m).ConfigureAwait(false);
            }
            string cardno = "";
            var list = await _memberCard.GetListAsync<ICasaMielSession>(data.mobile).ConfigureAwait(false);
            if (list.Count > 0) {
                var cardinfo = list.FirstOrDefault(c => c.IsBind == true);
                if (cardinfo != null) {
                    cardno = cardinfo.CardNO;
                }
            }
            var logdata = new UserLog { Url = Request.GetShortUri(), OPInfo = $"用户登陆", OPTime = DateTime.Now, UserName = data.mobile, UserIP = Request.GetUserIp() };
            await _mediator.Publish(new UserLogNoticeCommand(logdata)).ConfigureAwait(false);
            // await _userLog.AddAsync<ICasaMielSession>(logdata).ConfigureAwait(false);
            //string key = Constant.TOKEN_PREFIX + data.mobile + "_" + loginType;
            //_cacheService.Remove(key);

            var memberdata = new { Mobile = member.Mobile, Nick = member.Nick, Birthday = member.Birthday, Sex = member.Sex, TrueName = member.TrueName, Email = member.Email, cardno = cardno };
            return new JsonResult(new { code = 0, data = tokens, member = memberdata });
        }
        /// <summary>
        /// 我的会员券
        /// </summary>
        /// <param name="data"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        ///<remarks>
        ///1、	返回数据内容：
        ///{"code":0,"msg":"处理成功",
        ///"content":"{"cardno":"xxx","phoneno":"xxx","wxopenid":"xxx",
        ///"tickets":[{"cardno":"卡号","ticketid":xxxx,"ticketname":"券名称","tickettype":"券类型","source":"券来源方式","state":1,"je":xxx.xx,"makedate","2016-01-08""startdate","2016-01-08""enddate","2016-10-08","prange":[{"pid":xxx,"count":xxx},{"pid":xxx,"count":xxx},……]},
        ///{"cardno":"xxxx","ticketid":xxxx,"ticketname":"周年庆券","tickettype":"充值赠送券","source":"微信","state":1,
        ///"je":xxx.xx,"makedate","2016-01-08""startdate","2016-01-08""enddate","2016-10-08","prange":[{"pid":xxx,"count":xxx},{"pid":xxx,"count":xxx},……]},……]}","sign":"9ade8ba90cf38745bea56398d235daae"}
        ///</remarks>
        [HttpPost]
        [Route("[action]")]
        [ProducesResponseType(typeof(ZmodelExt), (int)HttpStatusCode.OK)]
        [ProducesResponseType((int)HttpStatusCode.NotFound)]
        [TypeFilterAttribute(typeof(CheckTokenAttribute))]
        public async Task<IActionResult> GetTicticket([FromBody] GetTicticketReq data, [FromHeader(Name = "u-token")] string token)
        {
            var mobile = MemberHelper.GetMobile(token);
            var cardlist = await _memberCard.GetListAsync<ICasaMielSession>(mobile).ConfigureAwait(false);
            if (cardlist == null)
                return Ok(new { code = -7, content = "", msg = "无此卡" });

            //var cardentity = await _memberCard.FindAsyncByCardnoMobile<ICasaMielSession>(data.cardno, mobile);
            var cardentity = cardlist.Where(c => c.CardNO == data.Cardno).SingleOrDefault();
            if (cardentity == null) {
                return Ok(new { code = -7, content = "", msg = "无此卡" });
            }

            var zmodel = await _iicApiService.Geticticket(data).ConfigureAwait(false);
            return Ok(zmodel);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [Route("[action]")]
        public async Task<IActionResult> TicketLimit()
        {
            var list = new List<long> { 4266094 };
            var cmd = new TicketLimitCommand(222105, list, 1);
            var res = await _mediator.Send(cmd).ConfigureAwait(false);

            var d = JsonConvert.DeserializeObject<TicketsRules>(res.content);
            return Ok(d);
        }
        /// <summary>
        /// 更改卡状态
        /// </summary>
        /// <param name="data"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("[action]")]
        [TypeFilterAttribute(typeof(CheckTokenAttribute))]
        public async Task<IActionResult> icrealcardadjust([FromBody]CardStateReq data, [FromHeader(Name = "u-token")]string token)
        {
            if (data == null) {
                throw new ArgumentNullException(nameof(data));
            }
            logger.Trace($"{JsonConvert.SerializeObject(data)}");
            var mobile = MemberHelper.GetMobile(token);
            data.Phoneno = mobile;
            var zmodel = await _iicApiService.IcRealCardAdjust(data).ConfigureAwait(false);
            var entity = await _memberCard.FindAsync<ICasaMielSession>(data.Cardno, mobile).ConfigureAwait(false);
            logger.Trace($"icrealcardadjust:{JsonConvert.SerializeObject(entity)}");
            if (entity != null) {
                if (zmodel.code == 0) {
                    entity.State = data.State;
                    await _memberCard.UpdateAsync<ICasaMielSession>(entity).ConfigureAwait(false);
                    var logdata = new UserLog { Url = Request.GetShortUri(), OPInfo = $"实体卡调整状态,卡号:[{data.Cardno}],状态：{data.State}", OPTime = DateTime.Now, UserName = mobile, UserIP = Request.GetUserIp() };
                    await _mediator.Publish(new UserLogNoticeCommand(logdata)).ConfigureAwait(false);
                    //  await _userLog.AddAsync<ICasaMielSession>(logdata).ConfigureAwait(false);
                }
            }
            return Ok(zmodel);
        }

        /// <summary>
        /// 实体卡状态
        /// </summary>
        /// <param name="token"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("[action]")]
        [TypeFilterAttribute(typeof(CheckTokenAttribute))]
        public async Task<IActionResult> GetCardState([FromHeader(Name = "u-token")]string token)
        {
            var mobile = MemberHelper.GetMobile(token);
            var list = await _memberCard.GetListAsync<ICasaMielSession>(mobile).ConfigureAwait(false);
            var card = list.Where(a => a.IsBind == true && a.CardType == "1").SingleOrDefault();
            if (card != null) {
                return Ok(new { code = 0, content = new { hascard = true, cardno = card.CardNO, state = card.State } });
            }
            return Ok(new { code = 0, content = new { hascard = false, cardno = "", state = "" } });
        }
        /// <summary>
        /// Gets the scene.
        /// </summary>
        /// <returns>The scene.</returns>
        /// <param name="req">Req.</param>
        [HttpPost]
        [Route("[action]")]
        public async Task<IActionResult> GetScene([FromBody] GetSceneReq req)
        {
            if (req == null) {
                throw new ArgumentNullException(nameof(req));
            }
            var userinfo = await _wxService.GetByIdAsync<ICasaMielSession>(req.Id).ConfigureAwait(false);
            if (userinfo == null) {
                var json = new JsonErrorResponse {
                    code = 999,
                    msg = "请重新打开小程序"
                };
                return new JsonResult(json);
            }

            if (!string.IsNullOrEmpty(req.Scene)) {
                Regex reg = new Regex(@"shopid=(\d*)");
                Match match = reg.Match(req.Scene);
                string value = match.Groups[1].Value;
                if (!string.IsNullOrEmpty(value)) {
                    var command = new CreateWxExtensionCommand(userinfo, value.ToInt32(0));
                    await _mediator.Send(command).ConfigureAwait(false);
                }
            } else {
                var command = new CreateWxExtensionCommand(userinfo, 0);
                await _mediator.Send(command).ConfigureAwait(false);
            }
            return Ok(new { code = 0, msg = "" });
        }

        /// <summary>
        /// Uns the authorization.
        /// </summary>
        /// <returns>The authorization.</returns>
        /// <param name="token">Token.</param>
        [HttpPost]
        [Route("[action]")]
        [TypeFilterAttribute(typeof(CheckTokenAttribute))]
        public async Task<IActionResult> UnAuthorization([FromHeader(Name = "u-token")]  string token)
        {
            var mobile = MemberHelper.GetMobile(token);
            await _wxService.UpdateByMoibleAsync<ICasaMielSession>(mobile).ConfigureAwait(false);
            var logoutcommand = new LogoutCommand(mobile, 3) { RequestUrl = Request.GetShortUri(), UserIP = Request.GetUserIp() };
            var result = await _mediator.Send(logoutcommand).ConfigureAwait(false);
            return Ok(new Zmodel { code = 0, msg = "操作成功" });
        }
    }
}